這邊簡介存儲電路(Storage Circuit)應如何在特定的情況下工作。
在這裡,有一些重要的術語和概念:
在 Storage Circuit,我們按照帳戶地址進行分組,並進一步根據存儲位置進行分組。每個子組中(每個帳戶的每個位置)的記錄都按照全局計數器的升序排列。存儲電路的目標是管理和驗證對存儲的訪問和修改。
記錄在訪問記錄中添加了一個額外的 val_prev,用於寫入存儲時使用。還有一個在總線映射中的額外值 is_first_touch,用於標記存儲位置在一個EOA呼叫中第一次被訪問時的狀態。
一個標準的總線映射查詢可以這樣進行:
bus_mapping_lookup(
gc,
Storage,
key,
val,
rw,
val_prev,
is_first_touch,
)
def check_storage(row: Row, row_prev: Row, row_next: Row, tables: Tables):
# 4.0. Unused keys are 0
assert row.field_tag() == 0
# 4.1. MPT lookup for last access to (address, storage_key)
# value = 0 means that the leaf doesn't exist. And this is needed by the non-existing proof.
is_non_exist = FQ(row.value == Word(0)) * FQ(row.initial_value == Word(0))
if not all_keys_eq(row, row_next):
tables.mpt_lookup(
row.address(),
is_non_exist * FQ(MPTProofType.NonExistingAccountProof)
+ (1 - is_non_exist) * FQ(MPTProofType.StorageMod),
row.storage_key(),
row.value,
row.initial_value,
row.root,
row_prev.root,
)
else:
assert row.root == row_prev.root